﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Navigation;
using DiagnosticCenter.Web;

namespace DiagnosticCenter.View
{
    public partial class viewTestingResult : Page
    {
        public DatabaseContext ctx = new DatabaseContext();
        public int ResultIDX = 44;

        public ResultInfo CurrentResult;
        private RadialViewModel DiagramContext1 = new RadialViewModel();
        private RadialViewModel DiagramContext2 = new RadialViewModel();

        public viewTestingResult()
        {
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            chartAnswers.DefaultView.ChartLegend.Visibility = System.Windows.Visibility.Collapsed;
            chartRating.DefaultView.ChartLegend.Visibility = System.Windows.Visibility.Collapsed;

            CurrentResult = new ResultInfo();
            ctx.Load(ctx.GetTblResultsTotalQuery(), LoadResultCompleted, null);
        }

        //NOTE: Fix - улучшить производительность
        private void LoadResultCompleted(LoadOperation<tblResult> lo)
        {
            var result = ctx.tblResults.Where(e => e.ResultID == ResultIDX).FirstOrDefault();

            CurrentResult.ResultID = result.ResultID;
            CurrentResult.UserID = result.UserID;
            CurrentResult.TestID = result.TestID;
            
            CurrentResult.UserName = String.Format("{0} {1}",result.tblUser.LastName, result.tblUser.FirstName);
            CurrentResult.UserGroup = result.tblUser.tblGroup.Name;
            CurrentResult.Subject = result.tblTest.tblSubject.FullName;
            CurrentResult.TestName = result.tblTest.TestName;
            CurrentResult.DateStart = result.DateStart.ToString();
            var ts1 = new TimeSpan(0, (int)result.tblTest.TotalTime, 0);
            CurrentResult.TotalTime = String.Format("{0:D2}:{1:D2} сек.", ts1.Minutes, ts1.Seconds);
            var ts2 = (TimeSpan)(result.DateFinish - result.DateStart);
            CurrentResult.UserTime = String.Format("{0:D2}:{1:D2} сек.",ts2.Minutes, ts2.Seconds);
            CurrentResult.TotalQuestions = result.tblTest.QuestionCount.ToString();
            CurrentResult.RightQuestions = result.RightAnswers.ToString();
            CurrentResult.TotalRating = String.Format("{0} баллов", result.tblTest.TestRating);
            CurrentResult.UserRating = String.Format("{0} баллов", result.Rating);

            foreach (var resultItem in result.tblResultItems)
            {
                var question = new QuestionItem(resultItem.tblQuestion.Text);

                //Чтение бинарных вопросов
                if ((AnswerType)resultItem.tblQuestion.AnswerType == AnswerType.AT_Binary)
                {
                    bool isTrued = Convert.ToBoolean(resultItem.IsRight);
                    bool isChecked = Convert.ToBoolean(Convert.ToInt32(resultItem.tblQuestion.AnswerLite));

                    question.Answers.Add(new AnswerItem("Да", isTrued, isChecked));
                    question.Answers.Add(new AnswerItem("Нет", !isTrued, !isChecked));
                }
                //Чтение остальных вопросов
                foreach (var answerInfo in resultItem.tblQuestion.tblAnswers)
                {
                    bool isChecked = false;

                    switch ((AnswerType)resultItem.tblQuestion.AnswerType)
                    {
                        case AnswerType.AT_SelectOne:
                            int temp = Convert.ToInt32(resultItem.ResultText);
                            if (answerInfo.AnswerID == temp)
                                isChecked = true;
                            break;
                        case AnswerType.AT_SelectMulti:
                            string[] stateMulti = resultItem.ResultText.Split(';');
                            for (var i = 0; i < stateMulti.Count(); i++ )
                            {
                                if (answerInfo.AnswerID == Convert.ToInt32(stateMulti[i]))
                                    isChecked = true;
                            }
                            break;
                        case AnswerType.AT_Relation:
                            break;
                        case AnswerType.AT_Arrange:
                            break;
                        case AnswerType.AT_SimpleText:
                            break;
                    }

                    var isTrue = Convert.ToBoolean(answerInfo.IsTrue);
                    question.Answers.Add(new AnswerItem(answerInfo.Text, isChecked, isTrue));
                }

                CurrentResult.ResultQuestions.Add(question);
            }

            gridResult.DataContext = CurrentResult;
            treeResults.ItemsSource = CurrentResult.ResultQuestions;

            DiagramContext1.Data.Add(Convert.ToDouble(result.tblTest.QuestionCount));
            DiagramContext1.Data.Add(Convert.ToDouble(result.tblTest.QuestionCount - result.RightAnswers));
            chartAnswers.ItemsSource = DiagramContext1.Data;

            DiagramContext2.Data.Add(Convert.ToDouble(result.tblTest.TestRating - result.Rating));
            DiagramContext2.Data.Add(Convert.ToDouble(result.Rating));
            chartRating.ItemsSource = DiagramContext2.Data;
        }
    }

    #region Results Tree
 

    public class CheckStateConverter : IValueConverter
    {
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool isChecked = (bool)value;

            if (isChecked)
            {
                return ToggleState.On;
            }
            else
            {
                return ToggleState.Off;
            }
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ToggleState checkState = (ToggleState)value;

            if (checkState == ToggleState.On)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    #endregion

    #region Result Information

    public class ResultInfo
    {
        public int ResultID { get; set; }
        public int UserID { get; set; }
        public int TestID { get; set; }

        public string UserName { get; set; }
        public string UserGroup { get; set; }
        public string Subject { get; set; }
        public string TestName { get; set; }
        public string DateStart { get; set; }
        public string TotalTime { get; set; }
        public string UserTime { get; set; }
        public string TotalQuestions { get; set; }
        public string RightQuestions { get; set; }
        public string TotalRating { get; set; }
        public string UserRating { get; set; }

        public ObservableCollection<QuestionItem> ResultQuestions;

        public ResultInfo()
        {
            ResultQuestions = new ObservableCollection<QuestionItem>();
        }
    }

    public class QuestionItem : INotifyPropertyChanged
    {
        private string text;
        public bool Expanded { get; set; }

        public QuestionItem(string text)
        {
            this.text = text;
            this.Expanded = true;
            Answers = new ObservableCollection<AnswerItem>();
        }

        public string Text
        {
            get
            {
                return this.text;
            }
            set
            {
                if (this.text != value)
                {
                    this.text = value;
                    this.NotifyPropertyChanged("Text");
                }
            }
        }

        public ObservableCollection<AnswerItem> Answers { get; set; }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }

    public class AnswerItem : INotifyPropertyChanged
    {
        private string text;
        private bool _check;

        public string Colored { get; set; }
        public string Bold { get; set; }

        //Почему-то все наоборот работает :-(
        public AnswerItem(string text, bool check, bool istrue)
        {
            this.text = text;
            _check = check;

            //Выбран и правилен
            if (_check && istrue)
            {
                Colored = "DarkBlue";
                Bold = "Bold";
            }
            //Выбран и неправилен
            else if (_check && !istrue)
            {
                Colored = "DarkRed";
                Bold = "Bold";
            }
            //Невыбран и правилен
            else if (!_check && istrue)
            {
                Colored = "DarkBlue"; 
            }
            //Невыбран и неправилен
            else
            {
                Colored = "Black";
            }
        }

        public string Text
        {
            get
            {
                return this.text;
            }
            set
            {
                if (this.text != value)
                {
                    this.text = value;
                    this.NotifyPropertyChanged("Text");
                }
            }
        }

        public bool Checked
        {
            get
            {
                return this._check;
            }
            set
            {
                if (this._check != value)
                {
                    this._check = value;
                    this.NotifyPropertyChanged("Checked");
                }
            }
        }
        
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }

    #endregion

    #region Result Chart
    public class RadialViewModel
    {
        public ObservableCollection<double> Data { get; private set; }
        public ObservableCollection<string> Series { get; private set; }

        //TODO: FIX: сделать правильную легенду
        public RadialViewModel()
        {
            Data = new ObservableCollection<double>();
            Series = new ObservableCollection<string> {"Правильно", "Неправильно"};
        }
    }

    #endregion
}

//TODO: NEW: Разрешение сохранение отчета
//TODO: NEW: Разрешение печать отчета